import logging
from datetime import timedelta, timezone

from fastapi import APIRouter, Query

from app.controllers.api import api_controller
from app.controllers.user import user_controller
from app.controllers.menu import menu_controller
from app.core.ctx import CTX_USER_ID
from app.core.dependency import DependAuth
from app.models.admin import Api, Role, User, MenuType
from app.models.enums import StatusType
from app.schemas.base import Fail, Success
from app.schemas.login import *
from app.schemas.users import UpdatePassword
from app.settings import settings
from app.utils.jwt_utils import create_access_token
from app.utils.password import get_password_hash, verify_password


log = logging.getLogger(__name__)
router = APIRouter()


@router.post("/access_token", summary="获取token")
async def login_access_token(credentials: CredentialsSchema):
    user: User = await user_controller.authenticate(credentials)
    await user_controller.update_last_login(user.id)
    access_token_expires = timedelta(minutes=settings.JWT_ACCESS_TOKEN_EXPIRE_MINUTES)
    expire = datetime.now(timezone.utc) + access_token_expires

    data = JWTOut(
        access_token=create_access_token(
            data=JWTPayload(
                user_id=user.id,
                username=user.username,
                is_superuser=user.is_superuser,
                exp=expire,
            )
        ),
        username=user.username,
    )
    return Success(data=data.model_dump())


@router.get("/userinfo", summary="查看用户信息", dependencies=[DependAuth])
async def get_userinfo():
    user_id = CTX_USER_ID.get()
    user = await User.filter(id=user_id).first()
    roles: list[Role] = await user.roles.filter(status=StatusType.ENABLED)

    data = await user.to_dict(exclude_fields=["password"])
    data["avatar"] = "https://avatars.githubusercontent.com/u/54677442?v=4"
    # 超级管理员的角色编码为super
    data["roles"] = [role.code for role in roles] if not data["is_superuser"] else ["super"]
    return Success(data=data)


@router.get("/user-codes", summary="查看菜单编码", dependencies=[DependAuth])
async def get_user_menu_codes():
    menus = await menu_controller.get_menu(CTX_USER_ID.get())
    # 过滤按钮类型
    menus = list(filter(lambda x: x.menu_type == MenuType.BUTTON, menus))

    return Success(data=[menu.code for menu in menus])


@router.get("/role-permissions", summary="查看角色权限", dependencies=[DependAuth])
async def role_permissions(role_id: int = Query(..., description="角色id")):
    menus = await menu_controller.find_by_role_id(role_id)
    apis = await api_controller.find_by_role_id(role_id)

    rst = {"menus": [menu.id for menu in menus], "apis": [api.id for api in apis]}

    return Success(data=rst)


@router.get("/usermenu", summary="查看用户菜单", dependencies=[DependAuth])
async def get_user_menu():
    menus = await menu_controller.get_menu(CTX_USER_ID.get())
    menus = [await menu.to_dict() for menu in menus]
    menus_dict = {menu["id"]: menu for menu in menus}

    # 转换成菜单树形结构
    for menu in menus:
        if menu["parent_id"] and menu["parent_id"] in menus_dict:
            if "children" not in menus_dict[menu["parent_id"]]:
                menus_dict[menu["parent_id"]]["children"] = []
            menus_dict[menu["parent_id"]]["children"].append(menu)

    rst = list(filter(lambda x: x["parent_id"] == 0, menus))
    return Success(data=rst)


@router.get("/vben-menu", summary="查看用户菜单", dependencies=[DependAuth])
async def get_vben_menu():
    user_id = CTX_USER_ID.get()
    rst = await menu_controller.get_vben_menu(user_id=user_id)
    return Success(data=rst)


@router.get("/all-vben-menu", summary="查看所有菜单", dependencies=[DependAuth])
async def all_vben_menu():
    rst = await menu_controller.get_vben_menu(None, False)
    return Success(data=rst)


@router.get("/userapi", summary="查看用户API", dependencies=[DependAuth])
async def get_user_api():
    user_id = CTX_USER_ID.get()
    user_obj = await User.filter(id=user_id).first()
    if user_obj.is_superuser:
        api_objs: list[Api] = await Api.all()
        apis = [api.method.lower() + api.path for api in api_objs]
        return Success(data=apis)
    role_objs: list[Role] = await user_obj.roles.filter(status=StatusType.ENABLED)
    apis = []
    for role_obj in role_objs:
        api_objs: list[Api] = await role_obj.apis
        apis.extend([api.method.lower() + api.path for api in api_objs])
    apis = list(set(apis))
    return Success(data=apis)


@router.post("/update_password", summary="修改密码", dependencies=[DependAuth])
async def update_user_password(req_in: UpdatePassword):
    user_id = CTX_USER_ID.get()
    user = await user_controller.get(user_id)
    verified = verify_password(req_in.old_password, user.password)
    if not verified:
        return Fail(msg="旧密码验证错误！")
    user.password = get_password_hash(req_in.new_password)
    await user.save()
    return Success(msg="修改成功")


@router.post("/logout", summary="用户登出", dependencies=[DependAuth])
async def logout():
    """
    用户登出接口
    """
    user_id = CTX_USER_ID.get()
    # 暂不用处理
    log.info("[%s]用户登出", user_id)

    return Success(msg="登出成功")
